﻿//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------

using Cinemachine;
using GameFramework;
using GameFramework.Fsm;
using System;
using UnityEngine;
using UnityGameFramework.Runtime;

namespace Adventure
{
    public class EnemyEntityBoar : EnemyEntity
    {
        public EnemyEntityData entityData;
        private IFsm<EnemyEntityBoar> fsm = null;
        private string fsmName;

        private static int Count;

        public EnemyEntityBoar()
        {
            fsmName = "Boar_" + (++Count);

            GameEntry.Fsm.CreateFsm<EnemyEntityBoar>(fsmName, this,
            new IdleStateBoar(),
            new PatrolStateBoar(),
            new AttackStateBoar(),
            new HitStateBoar(),
            new DeathStateBoar()
            );
        }

        protected override void OnInit(object userData)
        {
            base.OnInit(userData);

            groundOffset = new Vector2(-1.81f, -0.07f);
            touchLeftOffset = new Vector2(-1.29f, 0.55f);
            touchRightOffset = new Vector2(1.15f, 0.55f);

            rayOffsetPoint = new Vector2(0, 0.75f);

            normalSpeed = 0.5f;
            chaseSpeed = 1.2f;
        }

        protected override void OnShow(object userData)
        {
            base.OnShow(userData);

            if (userData != null)
            {
                entityData = (EnemyEntityData)userData;
            }
            
            fsm = GameEntry.Fsm.GetFsm<EnemyEntityBoar>(fsmName);    
            
            if (!fsm.IsRunning)
            {
                fsm.Start<PatrolStateBoar>();
            }
            
        }

        protected override void OnUpdate(float elapseSeconds, float realElapseSeconds)
        {
            base.OnUpdate(elapseSeconds, realElapseSeconds);         
        }
        protected override void OnRecycle()
        {
            base.OnRecycle();

            //TODO:这里不知道为什么不等物体销毁后执行，而是退出游戏立刻执行？
            // onrecycle只是回收到池里 不代表销毁，用OnDestroy
            //  GameEntry.Fsm.DestroyFsm(fsm);
         
        }
        private void OnDestroy()
        {
            
            GameEntry.Fsm.DestroyFsm(fsm);
        }    
    }

    public class IdleStateBoar : FsmState<EnemyEntityBoar>
    {
        private int timeId;

        protected override void OnEnter(IFsm<EnemyEntityBoar> fsm)
        {
            base.OnEnter(fsm);
            Log.Info("进入站立状态");

            
            timeId = GameEntry.TimerComponent.AddOnceTimer(2000, () =>
              {
                  if (fsm == null || fsm.Owner == null || fsm.Owner.transform == null) return;
                  fsm.Owner.transform.localScale = new Vector3(fsm.Owner.transform.localScale.x * -1, 1, 1);
                  fsm.Owner.groundOffset = new Vector2(fsm.Owner.groundOffset.x * -1, fsm.Owner.groundOffset.y);

                  ChangeState<PatrolStateBoar>(fsm);
              });
        }
        protected override void OnUpdate(IFsm<EnemyEntityBoar> fsm, float elapseSeconds, float realElapseSeconds)
        {
            base.OnUpdate(fsm, elapseSeconds, realElapseSeconds);

            if (fsm.Owner.currentHit)
            {
                ChangeState<HitStateBoar>(fsm);
                return;
            }

            fsm.Owner.rb.velocity = Vector2.zero;

            if (fsm.Owner.isGround && fsm.Owner.findPlayer)
            {
                ChangeState<AttackStateBoar>(fsm);
                GameEntry.TimerComponent.CancelTimer(timeId);
            }
        }
        protected override void OnLeave(IFsm<EnemyEntityBoar> fsm, bool isShutdown)
        {
            base.OnLeave(fsm, isShutdown);
        }

    }
    public class PatrolStateBoar : FsmState<EnemyEntityBoar>
    {
        private float delaytimer;
        protected override void OnEnter(IFsm<EnemyEntityBoar> fsm)
        {
            base.OnEnter(fsm);
            Log.Info("进入巡逻状态");

            fsm.Owner.currentSpeed = fsm.Owner.normalSpeed;
            fsm.Owner.animWalk = true;
            delaytimer = 0;
        }

        protected override void OnLeave(IFsm<EnemyEntityBoar> fsm, bool isShutdown)
        {
            base.OnLeave(fsm, isShutdown);

            fsm.Owner.animWalk = false;
            fsm.Owner.animRun = false;

        }
        protected override void OnUpdate(IFsm<EnemyEntityBoar> fsm, float elapseSeconds, float realElapseSeconds)
        {
            base.OnUpdate(fsm, elapseSeconds, realElapseSeconds);

            if (fsm.Owner.currentHit)
            {
                ChangeState<HitStateBoar>(fsm);
                return;
            }

            delaytimer += realElapseSeconds;


            fsm.Owner.rb.velocity = new Vector2(fsm.Owner.currentSpeed * fsm.Owner.faceDir.x * 100 * Time.deltaTime, fsm.Owner.rb.velocity.y);

            if (delaytimer < 0.2f)
            {
                return;
            }


            //这里应该是检测不精确的问题，所以转变方向后延迟一下检测
            bool leftCondition = fsm.Owner.touchLeftWall && fsm.Owner.faceDir.x < 0;//左脸对左检测器
            bool rightCondition = fsm.Owner.touchRightWall && fsm.Owner.faceDir.x > 0;//右脸对右检测器

            if (!fsm.Owner.isGround || leftCondition || rightCondition)
            {
                ChangeState<IdleStateBoar>(fsm);
            }

            if (fsm.Owner.findPlayer)
            {
                ChangeState<AttackStateBoar>(fsm);
            }
        }
    }
    public class AttackStateBoar : FsmState<EnemyEntityBoar>
    {
        private float delaytimer;
        private float losTimerTemp;
        private const float loseTimer = 1.5f;//丢失1.5秒内还维持之前状态
        private const float attackDistance = 1.2f;
        protected override void OnEnter(IFsm<EnemyEntityBoar> fsm)
        {
            base.OnEnter(fsm);
            Log.Info("进入攻击状态");

            fsm.Owner.animWalk = false;
            fsm.Owner.animRun = true;
            fsm.Owner.currentSpeed = fsm.Owner.chaseSpeed;
            delaytimer = 0;
            losTimerTemp = 0;

        }

        protected override void OnLeave(IFsm<EnemyEntityBoar> fsm, bool isShutdown)
        {
            base.OnLeave(fsm, isShutdown);

            fsm.Owner.animRun = false;
        }
        protected override void OnUpdate(IFsm<EnemyEntityBoar> fsm, float elapseSeconds, float realElapseSeconds)
        {
            base.OnUpdate(fsm, elapseSeconds, realElapseSeconds);

            if (fsm.Owner.currentHit)
            {
                ChangeState<HitStateBoar>(fsm);
                return;
            }

            if (fsm.Owner.playerTran && Vector2.Distance(fsm.Owner.transform.position, fsm.Owner.playerTran.position) > attackDistance)
            {
                fsm.Owner.animRun = true;
                if (fsm.Owner.currentSpeed < fsm.Owner.chaseSpeed)
                {
                    fsm.Owner.currentSpeed += 0.05f;
                }
                else
                {
                    fsm.Owner.currentSpeed = fsm.Owner.chaseSpeed;
                }

            }
            else
            {
                fsm.Owner.animRun = false;
                fsm.Owner.currentSpeed = 0;
            }

            fsm.Owner.rb.velocity = new Vector2(fsm.Owner.currentSpeed * fsm.Owner.faceDir.x * 100 * Time.deltaTime, fsm.Owner.rb.velocity.y);

            delaytimer += realElapseSeconds;
            if (delaytimer < 0.2f)
            {
                return;
            }

            //这里应该是检测不精确的问题，所以转变方向后延迟一下检测
            bool leftCondition = fsm.Owner.touchLeftWall && fsm.Owner.faceDir.x < 0;//左脸对左检测器
            bool rightCondition = fsm.Owner.touchRightWall && fsm.Owner.faceDir.x > 0;//右脸对右检测器

            if (!fsm.Owner.isGround || leftCondition || rightCondition)
            {
                ChangeState<IdleStateBoar>(fsm);
            }


            losTimerTemp += realElapseSeconds;
            if (!fsm.Owner.findPlayer && losTimerTemp >= loseTimer)
            {
                ChangeState<PatrolStateBoar>(fsm);
            }
        }
    }
    public class HitStateBoar : FsmState<EnemyEntityBoar>
    {

        protected override void OnEnter(IFsm<EnemyEntityBoar> fsm)
        {
            base.OnEnter(fsm);
            Log.Info("进入受伤状态");
            fsm.Owner.animHit = true;
            fsm.Owner.HitAddForce(GameObject.FindGameObjectWithTag("Player")?.GetComponent<PlayerEntity>());
        }
        protected override void OnLeave(IFsm<EnemyEntityBoar> fsm, bool isShutdown)
        {
            base.OnLeave(fsm, isShutdown);
            fsm.Owner.animHit = false;
        }

        protected override void OnUpdate(IFsm<EnemyEntityBoar> fsm, float elapseSeconds, float realElapseSeconds)
        {
            base.OnUpdate(fsm, elapseSeconds, realElapseSeconds);

            if (!fsm.Owner.currentHit)
            {
                ChangeState<PatrolStateBoar>(fsm);
            }
        }
    }
    public class DeathStateBoar : FsmState<EnemyEntityBoar>
    {

    }
}
